#pragma once

//@author A0096950U
#include <vector>
#include <assert.h>
#include "Display.h"
#include "Logger.h"
#include "Task.h"

class CurrentDisplay {
private:
	Display *mainDisplay;
	Display doneDisplay;
	Display todayTaskDisplay;
	Display searchResultDisplay;

	string feedback;
	string searchKeyword;

	Logger& logger;

	// Pre: nil
	// Post: sorts mainDisplay and doneDisplay by start time
	void sortByTime();

	// Pre: nil
	// Post: sorts mainDisplay and doneDisplay by date
	void sortByDate();

public:
	CurrentDisplay(void);

	// Pre: nil
	// Post: sort by time then by date
	void sortDisplay();

	// Pre: nil
	// Post: sets mainDisplay pointer to searchResultDisplay
	void setToSearchResult();

	// Pre: nil
	// Post: sets mainDisplay pointer to todayTaskDisplay
	void setToTodayTask();

	// Pre: newDisplay is already constructed
	// Post: Tasks with status TASK_ACTIVE are placed in mainDisplay
	//		 Tasks with status TASK_DONE are placed in doneDisplay
	//		 Previous displays are overwritten
	void setCurrentDisplay(vector<Task>& newDisplay);

	// Pre: nil
	// Post: returns a copy of Tasks in mainDisplay
	vector<Task> getMainDisplay() const;

	// Pre: nil
	// Post: returns a copy of Tasks in doneDisplay
	vector<Task> getDoneDisplay() const;

	// Pre: nil
	// Post: returns the size of main display
	int getMainDisplaySize() const;

	// Pre: nil
	// Post: returns the size of done display
	int getDoneDisplaySize() const;

	// Pre: taskToAdd is already constructed
	// Post: Tasks with status TASK_ACTIVE are placed in mainDisplay
	//		 Tasks with status TASK_DONE are placed in doneDisplay
	void push_back(Task& taskToAdd);

	// Pre: userIndex is valid, any userIndex exception to be thrown by caller
	// Post: Task at position userIndex is removed from mainDisplay
	void remove(int userIndex);

	// Pre:	nil
	// Post: Task with the corresponding taskID is removed from mainDisplay
	//		 If Task is not in mainDisplay or ID is invalid, do nothing
	void remove(string taskID);

	// Pre: nil
	// Post: mainDisplay and doneDisplay are emptied
	void clear();

	// Pre: newTask is already constructed
	// Post: Task with the same taskID as newTask in mainDisplay is updated
	//		 If Task is not in mainDisplay, do nothing
	void modify(Task& newTask);

	// Pre: userIndex is valid, any userIndex exception to be thrown by caller
	// Post: Task with corresponding userIndex moved
	//		 from mainDisplay to doneDisplay
	void setToDone(int userIndex);

	// Pre: Task with given taskID exists in doneDisplay
	// Post: Task with corresponding taskID moved
	//		 from doneDisplay to mainDisplay
	void undone(string taskID);

	// Pre: userIndex is valid, any userIndex exception to be thrown by caller
	// Post: returns the Task of corresponding userIndex in mainDisplay
	Task getMainDisplayTask(int userIndex) const;

	// Pre: nil
	// Post: returns feedback
	string getFeedback() const;

	// Pre: newFeedback is already constructed
	// Post: feedback updated to newFeedback
	void setFeedback(const string& newFeedback);

	// Pre: newFeedback is already constructed
	// Post: searchKeyword updated to keyword
	void setSearchKeyword(const string& keyword);

	// Pre: nil
	// Post: returns searchKeyword
	string getSearchKeyword() const;

	// Pre: nil
	// Post: returns true if current mainDisplay is searchResultDisplay
	bool isSearchResultDisplay() const;

	void setToOngoing(int userIndex);
	void setToOverdue(int userIndex);
};
